#include<iostream>
#include<queue>
#include<pthread.h>
#include<cstdio>
#include<cstdlib>
#include<unistd.h>

//安全队列
#define Max_Queue 5
template<class T>
class BlockQueue{
  private:
    int _capacity;
    std::queue<T> _q;
    pthread_mutex_t _mutex;
    pthread_cond_t _pro;
    pthread_cond_t _con;
  public:
    BlockQueue(int capacity = Max_Queue):_capacity(capacity)
  {
    pthread_mutex_init(&_mutex,NULL);
    pthread_cond_init(&_pro,NULL);
    pthread_cond_init(&_con,NULL);
  }
    ~BlockQueue()
    {
      pthread_mutex_destroy(&_mutex);
      pthread_cond_destroy(&_pro);
      pthread_cond_destroy(&_con);
    }

    bool Push(const T&data)
    {
      pthread_mutex_lock(&_mutex);
      while(_q.size()==_capacity)
      {
        pthread_cond_wait(&_pro,&_mutex);
      }
      _q.push(data);
      pthread_cond_signal(&_con);
      pthread_mutex_unlock(&_mutex);
    }
    bool Pop(T*data)
    {
      pthread_mutex_lock(&_mutex);
      while(_q.empty())
      {
        pthread_cond_wait(&_con,&_mutex);
      }
      *data=_q.front();
      _q.pop();
      pthread_cond_signal(&_pro);
      pthread_mutex_unlock(&_mutex);
    }
};
//线程池实现
//任务类
template<class T>
class ThreadTask{
  public:
    //定义函数指针
    typedef void (*Handler)(T);
    //初始化任务
    ThreadTask()
    {}
    //传递任务的数据和任务的处理函数
    ThreadTask(const T&data,Handler handler)
      :_data(data),_handler(handler)
    {}
    void Start()
    {
      return _handler(_data);
    }
  private:
    T _data;
    Handler _handler;
};
//线程池类
template<class T>
class ThreadPool{
  private:
    //线程入口函数
    static void* pthread_entry(void*arg)
    {
      ThreadPool* pool = (ThreadPool*)arg;
      while(1)
      {
        //从队列中取出一个任务
        ThreadTask<T> task;
        pool->_queue.Pop(&task);
        //调用Start()处理任务
        task.Start();
      }
    }
  public:
    ThreadPool(int thread_max,int queue_max)
      :_thread_max(thread_max),_queue(queue_max)
    {
      int ret;
      pthread_t tid;
      //创建线程
      for(int i=0;i<thread_max;++i)
      {
        ret=pthread_create(&tid,NULL,pthread_entry,this);
        if(ret!=0)
        {
          printf("pthread_create error\n");
          exit(-1);
        }
      }
    }
    //将任务添加到安全队列中
    bool Push(ThreadTask<T>&task)
    {
      _queue.Push(task);
      return true;
    }
  private:
    int _thread_max; //线程数量
    BlockQueue<ThreadTask<T>> _queue;//任务安全队列

};
void Print(int data)
{
  printf("%p thread,run data:%d\n",pthread_self(),data);
  sleep((data%3)+1);
}
int main()
{
  ThreadPool<int> p(5,10);
  for(int i=0;i<10;++i)
  {
    ThreadTask<int> task(i,Print);
    p.Push(task);
  }
  while(1)
  {
    sleep(1);
  }
  return 0;
}
